package puppy.servlet;

import java.io.IOException;
import java.util.Collections;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import puppy.db1.DBHandler;
import puppy.webData.UrlData;
import puppy.webData.UserFormData;

/**
 * Servlet implementation class URLSurvey
 */
public class URLSurvey extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public URLSurvey() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub

		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub

		HttpSession session = request.getSession();

		if (session.getAttribute(ServletInitValues.query) == null) {

			initializeUser(session);
			
			
			response.sendRedirect(ServletInitValues.formPage);
			/*RequestDispatcher view = request
			.getRequestDispatcher(ServletInitValues.formPage);
			view.forward(request, response);
			return;*/
			

		} else {

			Map parameters = request.getParameterMap();
			LinkedList<UserFormData> data = new LinkedList<UserFormData>();

			boolean[] missingValue = getFieldValues(request, parameters, data);

			boolean flag= hasAnError(missingValue);
			
			request.getSession().setAttribute(ServletInitValues.errorFlag, flag);
			
			session.setAttribute(ServletInitValues.webEntryFeedback, data);
			request.getSession().setAttribute(ServletInitValues.error, missingValue);
			
			
			/**
			 * Store feedback information in the session
			 * 
			 * session is also updated: new url is set if more pages are
			 * available for evaluation for the current query, otherwise db is
			 * updated with all the feedback collected
			 */
			 System.out.println("data:" +data + "\t" + hasAnError(missingValue));

			if (data != null && !hasAnError(missingValue)) {

				updateFeedbackInformation(data, session);
				
				//return;
				
			int i = (Integer) session.getAttribute(ServletInitValues.surveys);
			i++;
			if(i>=ServletInitValues.maxSuverys){
				
				session.setAttribute(ServletInitValues.surveys, 0);
				response.sendRedirect(ServletInitValues.submitted);
								
			}else{
				
				
				session.setAttribute(ServletInitValues.surveys, i);
				response.sendRedirect(ServletInitValues.formPage);
			}	
			
				
				
			
				/*RequestDispatcher view = request
						.getRequestDispatcher(ServletInitValues.submitted);
				view.forward(request, response);

				return;*/
				

			}else{
				
				
				response.sendRedirect(ServletInitValues.formPage);
				/*RequestDispatcher view = request
				.getRequestDispatcher(ServletInitValues.formPage);
				view.forward(request, response);
				
				return;*/
				
			}
		}

		
	/*	//return;
		RequestDispatcher view = request
				.getRequestDispatcher(ServletInitValues.formPage);
		view.forward(request, response);

		return;*/

	}

	
	
	public boolean hasAnError(boolean s[]){
			
	
		for(int i=0; i < s.length; i++){
			
			if(s[i]) return true;
			
			
		}
		return false;
			
	}
	
	public static void combineURLS(Hashtable<UrlData, Integer> webURLs,
			int queryId, int kidsquery) {

		LinkedList<UrlData> urls = DBHandler.getUrlDataForQuery((long) queryId);

		LinkedList<UrlData> urlsKids = DBHandler
				.getUrlDataForQuery((long) kidsquery);

		for (int i = 0; i < urls.size(); i++) {

			webURLs.put(urls.get(i), queryId);

		}

		for (int i = 0; i < urlsKids.size(); i++) {

			webURLs.put(urlsKids.get(i), kidsquery);

		}

	}
	public static void initializeUser(HttpSession session) {
		// TODO Auto-generated method stub

		int queryID = puppy.db1.DBHandler.getNextQuery(ServletInitValues.EvaluateTopN);
		
		int kidsquery = puppy.db1.DBHandler.getKidsVersionQuery(queryID);
		LinkedList<UrlData> webURLs = new LinkedList<UrlData>(); 
		System.out.println(kidsquery);
		puppy.db1.DBHandler.increaseQueryReviews((long)queryID);
		puppy.db1.DBHandler.increaseQueryReviews((long)kidsquery);
		
		
		LinkedList<UserFormData> webFeedback = new LinkedList<UserFormData>();

		LinkedList<UrlData> urls = DBHandler
				.getUrlDataForQuery((long) queryID);
		
		LinkedList<UrlData> urlsKids = DBHandler
		.getUrlDataForQuery((long) kidsquery);
		
		
		System.out.println(urls.size());
		System.out.println(urlsKids.size());
		webURLs.addAll(urls);
		webURLs.addAll(urlsKids);
		
		
		System.out.println(webURLs);
		Collections.shuffle(webURLs);

		System.out.println(webURLs);
		
		if (webURLs != null && webURLs.size() > 0) {

			
			System.out.println("entro---------");
		//	session.setAttribute(ServletInitValues.queryID, queryID);

			String query[] = DBHandler.getQueryInfo((long) queryID);

			session.setAttribute(ServletInitValues.query, query[1]);

			session.setAttribute(ServletInitValues.webEntryFeedback,
					webFeedback);
			session.setAttribute(ServletInitValues.webURLS, webURLs);
			
			
			Integer i = (Integer)session.getAttribute(ServletInitValues.surveys);
			
			if(i==null || (i!=null && i>=ServletInitValues.maxSuverys)){
				
				session.setAttribute(ServletInitValues.surveys,0);
			}
			//session.setAttribute(ServletInitValues.surveys,0);

			//System.out.println("Agregando weburls:"+ webURLs.size());
			
			// error variable
			session.setAttribute(ServletInitValues.error, null);
			session.setAttribute(ServletInitValues.errorFlag, false);

		}

	}

	
	synchronized void updateFeedbackInformation(LinkedList<UserFormData> data,
			HttpSession session) {
		// TODO Auto-generated method stub

		

		LinkedList<UrlData> urls = (LinkedList<UrlData>) session
				.getAttribute(ServletInitValues.webURLS);

		if (urls != null) {

			for (int i = 0; i < urls.size(); i++) {

				System.out.println("Entro update user information");
				DBHandler.insertUserFormInstance(data.get(i), urls
						.get(i).getUrl());

			}

		}

		data.clear();
		data = null;

		urls.clear();
		urls = null;

		session.setAttribute(ServletInitValues.webEntryFeedback, null);
		session.setAttribute(ServletInitValues.webURLS, null);
		session.setAttribute(ServletInitValues.query, null);
	//	session.setAttribute(ServletInitValues.queryID, null);
		session.setAttribute(ServletInitValues.error, null);
		session.setAttribute(ServletInitValues.errorFlag,false);
		//session.setAttribute(ServletInitValues.surveys,0);
		session.setAttribute(ServletInitValues.formRelevancyValues, null);
		session.setAttribute(ServletInitValues.formAppValues, null);

	}
	
	private boolean[] getFieldValues(HttpServletRequest request,
			Map parameters, LinkedList<UserFormData> list) {
		// TODO Auto-generated method stub

		System.out.println("Form values");

		LinkedList<UrlData> urls = (LinkedList<UrlData>) request.getSession()
				.getAttribute(ServletInitValues.webURLS);

		boolean missingValue[] = new boolean[urls.size()];

		for (int i = 0; i < urls.size(); i++) {
			missingValue[i] = false;
			UserFormData data = new UserFormData();

			if (parameters.containsKey(ServletInitValues.formRelevant+urls.get(i).getId())) {

				int relevant = Integer.valueOf(request
						.getParameter(ServletInitValues.formRelevant+urls.get(i).getId()));
				data.setRelevancy(relevant);

			} else {
				missingValue[i] = true;

			}

			if (parameters.containsKey(ServletInitValues.formKidsApp+urls.get(i).getId())) {

				int relevant = Integer.valueOf(request
						.getParameter(ServletInitValues.formKidsApp+urls.get(i).getId()));
				data.setAppropriate(relevant);

			} else {
				missingValue[i] = true;

			}

			data.setSqlDate(new java.sql.Timestamp((new java.util.Date())
					.getTime()));

			data.setUserID(request.getSession().getId());

			list.add(data);

		}

		
		return missingValue;
	}

}